package cz.acies.uniql.sql;

import java.io.Serializable;
import java.util.HashMap;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.dom.DOMElement;


import cz.acies.uniql.dialect.Dialect;
import cz.acies.uniql.metadata.DBMetaData;

public class UniQLExpr implements Cloneable,  Serializable
{
	private static final long serialVersionUID = 6584639952330203114L;
	
	private Dialect dialect; 
	private DBMetaData dbmd;
	private String id;
	private String name;
	private HashMap<String, Object> aliasMap;
	private UniQLExpr parent;
	
	/**
	 * Konstructor UniQLExpr.
	 */
	public UniQLExpr() {
	}

	/**
	 * Konstructor UniQLExpr.
	 * 
	 * @param dialect the dialect
	 */
	public UniQLExpr(Dialect dialect) {
		this(dialect, null);
	}

	/**
	 * Konstructor UniQLExpr.
	 * 
	 * @param dialect
	 * @param name
	 */
	public UniQLExpr(Dialect dialect, String name) {
		super();
		this.setDialect(dialect);
		this.setName(name);
	}
	 
	// -----  -----------------------------------------------------------------
	
	/**
	 * Funkce transformuje objekt UniQLExpr na String v z�vislosti na typu dialektu
	 * 
	 * @return
	 * Funkce transformuje objekt UniQLExpr na String v z�vislosti na typu dialektu
	 */
	public String translate() throws Exception {
		return "";
	}
	
	/**
	 * Funkce p�etransformuje �et�zec sql na objekt type UniQLExpr
	 * @param sql - 
	 * @return
	 */
	public UniQLExpr parse(String sql) {
		return this;
	}

	// ----- -----------------------------------------------------------------

	/**
	 * Metoda odstran� v�echny doposud p�idan� elementy. Priv�tn� prom�bb� nastav� 
	 * na defauln� hodnoty.
	 *  
	 */
	public UniQLExpr clear() {
		id = null;
		name = null;
		aliasMap.clear();
		aliasMap = null;
		return this;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#clone()
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Object clone() throws CloneNotSupportedException {
		Object clone = super.clone();
		assert clone instanceof UniQLExpr;
		((UniQLExpr) clone).setId(this.id);
		((UniQLExpr) clone).setName(this.name);
		((UniQLExpr) clone).setDialect(dialect);
		((UniQLExpr) clone).setAliasMap((aliasMap != null) ? (HashMap<String, Object>) aliasMap.clone() : null);
		return clone;
	}

	// ----- Getter & Setter --------------------------------------------------

	/**
	 * Zada hodnotu aliasMap.
	 * 
	 * @param aliasMap nova hodnota aliasMap
	 */
	public void setAliasMap(HashMap<String, Object> aliasMap) {
		this.aliasMap = aliasMap;
	}
	
	/**
	 * Navraci hodnotu aliasMap.
	 * 
	 * @return vraci hodnotu promenn� aliasMap
	 */
	public HashMap<String, Object> getAliasMap() {
		if (this.aliasMap == null) {
			setAliasMap(new HashMap<String, Object>());
		}
		return aliasMap;
	}

	/**
	 * Vr�t� hodnotu prom�nn� dialect.
	 * 
	 * @return Vr�t� hodnotu prom�nn� dialect
	 */	
	public Dialect getDialect() {
		return dialect;
	}

	/**
	 * Nastav� priv�tn� prom�nnou dialect.
	 * 
	 * @param dialect prom�nn� typu dialect
	 */	
	public void setDialect(Dialect dialect) {
		this.dialect = dialect;
		/*if (getAliasMap() == null) {
			setAliasMap(new HashMap<String, Object>());
		}
		getAliasMap().put("dialect", dialect);*/
	}
	
	/**
	 * Navraci hodnotu dB meta data.
	 * 
	 * @return - vraci hodnotu dB meta data
	 */
	public DBMetaData dbmd() {
		/*if (dbmd==null)
			dbmd = (DBMetaData)getAliasMap().get("dbmd");*/
		return dbmd;
		//return (DBMetaData)getAliasMap().get("dbmd");
	}
	
	/**
	 * Navraci hodnotu dB meta data.
	 * 
	 * @return - vraci hodnotu dB meta data
	 */
	public DBMetaData getDBMetaData() {
		return this.dbmd();
	}
	
	/**
	 * Zada hodnotu dB meta data.
	 * 
	 * @param dbmd nova hodnota dB meta data
	 */
	public void setDBMetaData(DBMetaData dbmd) {
		this.dbmd = dbmd;
		/*if (getAliasMap() == null) {
			setAliasMap(new HashMap<String, Object>());
		}
		getAliasMap().put("dbmd", dbmd);*/
	}
	
	public void setUniQLProperties(UniQLExpr expr) {
		this.setAliasMap(expr.getAliasMap());
		this.setDialect(expr.getDialect());
		this.setDBMetaData(expr.dbmd());
	}

	/**
	 * Vr�t� hodnotu prom�nn� name.
	 * 
	 * @return Vr�t� hodnotu prom�nn� name
	 */
	public String getName() {
		return name;
	}

	/**
	 * Nastav� priv�tn� prom�nnou name.
	 * 
	 * @param dialect prom�nn� typu dialect
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Vr�t� hodnotu prom�nn� id.
	 * 
	 * @return Vr�c� hodnotu prom�nn� id
	 */
	public String getId() {
		return id;
	}

	/**
	 * Nastav� priv�tn� prom�nnou id.
	 * 
	 * @param id prom�nn� typu String
	 */
	public void setId(String id) {
		this.id = id;
	}
	
	// ----- -----------------------------------------------------------------
	
	public UniQLExpr getParent() {
		return parent;
	}

	public void setParent(UniQLExpr parent) {
		this.parent = parent;
	}

	// ----- -----------------------------------------------------------------
	
	public String toString() {
		//String classname = this.getClass().getName();
		String classname = this.getClass().getSimpleName();
		return ""+classname+" ( " + name + " ):\n\t" + "id(" + id + ")\n\t" + "dialect(" + dialect + ")\n\t" + "aliasMap" + aliasMap + "\n" + ")";
	}
	
	// -----  -----------------------------------------------------------------
	
	/**
	 * Funkce p�etransformuje objekt typu UniQLExpr do XML
	 * @param 
	 * @return String - n�vratov� hodnota je �et�zec XML
	 */
	public String transToXML() throws Exception {
		return null;
	}

	/**
	 * Funkce p�etransformuje objekt typu UniQLExpr do objekt typu DOMElement 
	 * @param DOMElement node 
	 * @return DOMElement
	 */
	public DOMElement transToXML(DOMElement node) throws Exception {
		return null;
	}

	/**
	 * Funkce p�etransformuje �et�zec XML na objekt typu UniQLExpr 
	 * @param String xml 
	 * @return UniQLExpr
	 */
	public UniQLExpr xmlToExpr(String xml) throws Exception {
		Document doc = DocumentHelper.parseText(xml);
		return xmlToExpr(doc.getRootElement());
	}

	/**
	 * Funkce p�etransformuje objekt typu org.dom4j.Element na objekt typu UniQLExpr 
	 * @param Element node
	 * @return UniQLExpr
	 */	
	public UniQLExpr xmlToExpr(Element node) throws Exception {
		System.out.println("UniQLExpr.xmlToExpr()");
		return this;
	}

}
